#include "htf_url_parser.h"
#include "htf_logger.h"
#include <string.h>
#include <stdlib.h>

static int hex_char_to_int(char c) {
    if (c >= '0' && c <= '9') return c - '0';
    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
    if (c >= 'A' && c <= 'F') return c - 'A' + 10;
    return -1;
}

static int parse_hex_key(const char* hex_str, uint8_t* out, size_t max_len) {
    size_t len = strlen(hex_str);
    if (len % 2 != 0 || len / 2 > max_len) return -1;
    for (size_t i = 0; i < len; i += 2) {
        int hi = hex_char_to_int(hex_str[i]);
        int lo = hex_char_to_int(hex_str[i+1]);
        if (hi < 0 || lo < 0) return -1;
        out[i/2] = (hi << 4) | lo;
    }
    return (int)(len / 2);
}

int htf_parse_model_url(const char* url, htf_model_config_t* out) {
    if (!url || !out) return -1;

    const char* qmark = strchr(url, '?');
    if (!qmark) {
        // No params: use default
        strncpy(out->base_path, url, sizeof(out->base_path) - 1);
        out->base_path[sizeof(out->base_path)-1] = '\0';
        out->key_len = 32;
        memset(out->key, 0, 32); // Default key (all zeros)
        out->backend_type = 0;   // Default MindSpore（lite）
        out->has_key = 0;
        return 0;
    }

    // Copy base path
    size_t base_len = qmark - url;
    if (base_len >= sizeof(out->base_path)) return -2;
    memcpy(out->base_path, url, base_len);
    out->base_path[base_len] = '\0';

    // Parse query: key=hex:...&backend=mindspore（lite）
    const char* query = qmark + 1;
    char* dup = strdup(query);
    char* token = strtok(dup, "&");
    out->backend_type = 0;
    out->has_key = 0;
    out->key_len = 0;

    while (token) {
        if (strncmp(token, "key=hex:", 8) == 0) {
            int len = parse_hex_key(token + 8, out->key, 32);
            if (len == 32) {
                out->key_len = 32;
                out->has_key = 1;
            }
        } else if (strcmp(token, "backend=native") == 0) {
            out->backend_type = 1;
        } else if (strcmp(token, "backend=mindspore") == 0) {
            out->backend_type = 0;
        }
        token = strtok(NULL, "&");
    }

    if (!out->has_key) {
        memset(out->key, 0, 32);
        out->key_len = 32;
    }

    free(dup);
    return 0;
}